package com.jmx.tomcat.dispatcher;

import com.jmx.tomcat.servlet.api.Servlet;
import com.jmx.tomcat.worker.RequestHandlerThread;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.logging.LogManager;
import java.util.logging.Logger;


/**
 * 监听本地8888端口，等待客户端连接，并调度任务
 *
 * @author: jmx
 * @date: 2023-08-09 14:02
 * @version: 1.0
 */
public class Server {
    //pattern和servlet类名的映射
    public static final Map<String, String> patternMap = new ConcurrentHashMap<>();
    public static final Map<String, Servlet> servletMap = new ConcurrentHashMap<>();
    //添加线程池 动态维持线程数为 10~20
    private static final ExecutorService poolExecutor = new ThreadPoolExecutor(10, 20,
            8, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(50),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());
    //服务器端口号
    public static final int PORT = 8888;
    //日志
    private static final Logger logger = Logger.getLogger(Servlet.class.getName());

    public void start() throws Exception {
        // 加载配置文件
        LogManager.getLogManager().readConfiguration(
                Server.class.getResourceAsStream("/logging.properties")
        );
        if (patternMap.isEmpty()) {
            logger.warning("patternMap 没有元素");
        }
        if (servletMap.isEmpty()) {
            logger.warning("servletMap 没有元素");
        }
        ServerSocket serverSocket = new ServerSocket(PORT);
        logger.info(String.format("=======服务器在%d端口监听=======", PORT));
        while (!serverSocket.isClosed()) {
            Socket socket = serverSocket.accept();
            //从线程池获取线程执行
            logger.info("ip【"+socket.getInetAddress().getHostAddress()+"】 访问本服务器");
            poolExecutor.submit(new RequestHandlerThread(socket));
        }
    }

    static {
        // 获取当前类的ClassLoader
        ClassLoader classLoader = Server.class.getClassLoader();

        // 获取资源的URL
        URL resourceURL = classLoader.getResource("web.xml");
        String path = resourceURL.getPath();
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(new File(path));
            Element rootElement = document.getRootElement();
            List<Element> servlets = rootElement.elements("servlet");
            List<Element> mappings = rootElement.elements("servlet-mapping");
            for (Element servlet : servlets) {
                Element cls = servlet.element("servlet-class");
                Element name = servlet.element("servlet-name");
                Servlet obj = (Servlet) Class.forName(cls.getText()).newInstance();
                servletMap.put(name.getText(), obj);
                logger.info("servlet 容器初始化完成");
            }
            for (Element mapping : mappings) {
                Element name = mapping.element("servlet-name");
                Element url = mapping.element("url-pattern");
                patternMap.put(url.getText(), name.getText());
                logger.info("路径映射初始化完成");
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
